using UnityEngine;
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;


public class CSdPeer_UDP : CSdSocket_UDP
{
    CProtocolMgr proMgr = null;
    int peerType = 0;//  1: connector 2: listener
    Hashtable peers = null;
    public bool Connect(string ip, int port, CProtocolMgr pm)
    {
        if (peerType != 0)
        {
            return false;
        }
        try
        {
            if (pm == null)
            {
                return false;
            }
            proMgr = pm;
            IPAddress address = IPAddress.Parse(ip);
            targetPoint = new IPEndPoint(address, port);
            remotePoint = targetPoint;
            s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            s.Blocking = false;
            s.EnableBroadcast = true;
            peerType = 1;
            return true;
        }
        catch (System.Exception ex)
        {
            UnityEngine.Debug.Log("connect err:" + ex.Message);
        }
        UnityEngine.Debug.Log("connect failed:");
        return false;
    }
    public bool StartListen(string ip, int port, CProtocolMgr pm)
    {
        if (peerType != 0)
        {
            return false;
        }
        try
        {
            if (pm == null)
            {
                return false;
            }
            proMgr = pm;
            //IPAddress address = IPAddress.Parse(ip);
            //targetPoint = new IPEndPoint(address, port);
            targetPoint = new IPEndPoint(IPAddress.Any, port);

            IPEndPoint incoming = new IPEndPoint(IPAddress.Any, 0);
            remotePoint = (EndPoint)incoming;

            s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            s.Blocking = false;
            s.Bind(targetPoint);
            peerType = 2;
            peers = new Hashtable();
            return true;
        }
        catch (System.Exception )
        {
        }
        return false;
    }

    public void Run()
    {
        try
        {
            if (peerType == 0)
            {
                return;
            }
            int recvcount = 0;
            byte[] recvbuf = RecvAndReturn(ref recvcount);
            if (recvbuf != null && proMgr != null)
            {
                //switch here
                CSdSocket_UDP peer = null;
                if (peerType == 1)
                {
                    peer = this;
                }
                else if (peerType == 2)
                {
                    //found the peer or create one
                    if (peers.Contains(remotePoint))
                    {
                        peer = (CSdSocket_UDP)peers[remotePoint];
                    }
                    else
                    {
                        peer = new CSdSocket_UDP();
                        peer.Attach(s);
                        peer.targetPoint = remotePoint;
                        peers[remotePoint] = peer;
                    }
                }
                int movetohead = proMgr.Handle(recvbuf, recvcount, peer);
                while (movetohead > 0 && recvcount >= 0)
                {
                    SetRecvIndex(movetohead);
                    recvcount -= movetohead;
                    movetohead = proMgr.Handle(recvbuf, recvcount, peer);
                }
            }

        }
        catch (System.Exception)
        {

        }
    }
}
